﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using GCC.APIContainer.Utilities;
using GCC.Container.Abstracts;
using GCC.Container.Models;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

using tcm.entity;
using tcm.entity.System;
using tcm.utils;
using tcm.request.System;
using Microsoft.Extensions.Options;
using tcm.Filters;

namespace tcm.Controller.SystemManage
{
    [ApiController]
    [Route("tcm/login")]
    public class SysLoginController : GCCAPIControllerBase
    {
        private readonly AbsGCCContext _context;

        public SysLoginController(AbsGCCContext context) : base(context)
        {
            _context = context;
        }


        /// <summary>
        /// 登录
        /// </summary>
        /// <returns></returns>
        [HttpPost("login")]
        public DataResponse<string> Login([FromBody] SysLoginRequest request)
        {
            var userInfo = new LoginUser();
            var token = string.Empty;
            if (request==null)
                return SystemError<string>("请求参数错误");

            //if (string.IsNullOrWhiteSpace(request.code))
            //    return SystemError<string>("验证码不能为空");

            //var code = _context.TryGet<int>(request.uuid).Result;
            //if (code.ToString()!=request.code)
            //    return SystemError<string>("验证码不正确");

            request.login_IP = SysHelper.GetClientUserIp(HttpContext);

            //密码md5
            request.password = SysHelper.Md5(request.password);
            SysUser sysUser = GetUser(request);
            if (sysUser==null||sysUser.id<=0)
                return SystemError<string>("账号不存在，请重新输入");
            if (sysUser.password!= request.password)
                return SystemError<string>("密码不正确，请重新输入");
            if (sysUser.status == 0)
                return SystemError<string>("账号被禁用，请联系管理员");
            try
            {
                //获取角色
                var roles = GetRoles(sysUser.id);
                var permissions = new List<string>();
                if (roles!=null)
                    permissions=GetPermission(roles.Select(r => r.id).ToList(), sysUser);
                token = AuthManager.EncryptStringToBytes_Aes($"{sysUser.id}");
                sysUser.token= token;


                userInfo = new(sysUser, roles, permissions);
                //登录成功
                UpdateUser(sysUser, request.login_IP);

                Logger.Information(String.Format("账号{0}登录成功，IP：{1}", sysUser.user_name, sysUser.login_ip), _context.EventID);
                _context.Set<LoginUser>(token, userInfo, new CacheItemSettings()
                {
                    SaveToAll = true,
                    SlidingExpiration = TimeSpan.FromSeconds(GlobalConstant.CacheSecond),
                }).Wait();
            }
            catch (Exception exc)
            {
                Logger.Error(String.Format("账号{0}登录失败，IP：{1}，原因{2}", sysUser.user_name, sysUser.login_ip, exc.Message), _context.EventID, exc);
            }

            //userInfo.token = JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(userInfo));
            return HandleData(token);
        }


        /// <summary>
        /// 登出
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpDelete("logout")]

        public DataResponse<bool> Logout()
        {
            var token = HttpContext.GetToken();
            var userInfo = AuthManager.GetUserInfoByToken(_context, token);
            if (userInfo!=null)
            {
                if (!string.IsNullOrWhiteSpace(token))
                    _ = _context.Remove(token);

                Logger.Information(String.Format("账号{0}登出。", userInfo.user_name), _context.EventID);
            }

            return HandleData(true);
        }


        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("getUser")]
        public DataResponse<LoginUser> GetUserInfo()
        {
            var token = HttpContext.GetToken();
            var userInfo = AuthManager.GetUserInfoByToken(_context, token);
            if (userInfo==null)
                return HandleData(userInfo);
            var sysUser = GCCEntrance.DBManager!.LocalDB!.Select<SysUser>(userInfo.user_id).First();

            try
            {
                if (sysUser!=null)
                {
                    //获取角色
                    var roles = GetRoles(sysUser.id);

                    var permissions = new List<string>();
                    if (roles!=null)
                        permissions=GetPermission(roles.Select(r => r.id).ToList(), sysUser);
                    userInfo=new LoginUser(sysUser, roles, permissions);

                    //刷新权限
                    _context.Remove(token).Wait();
                    _context.Set<LoginUser>(token, userInfo, new CacheItemSettings()
                    {
                        SaveToAll = true,
                        SlidingExpiration = TimeSpan.FromSeconds(GlobalConstant.CacheSecond),
                    }).Wait();
                }
            }
            catch (Exception exc)
            {
                Logger.Error(String.Format("账号{0}获取用户信息失败，原因{1}", sysUser.user_name, exc.Message), _context.EventID, exc);
            }

            return HandleData(userInfo);
        }


        /// <summary>
        /// 生成图片验证码
        /// </summary>
        /// <returns></returns>
        [HttpGet("captchaImage")]
        public DataResponse<LoginCaptcha> CaptchaImage()
        {
            string uuid = Guid.NewGuid().ToString().Replace("-", "");

            Tuple<string, int> captchaCode = CaptchaHelper.GetCaptchaCode();
            byte[] bytes = CaptchaHelper.CreateCaptchaImage(captchaCode.Item1);

            string base64Str = Convert.ToBase64String(bytes);
            _context.Set<int>(uuid, captchaCode.Item2, new CacheItemSettings()
            {
                SaveToAll = true,
                SlidingExpiration = TimeSpan.FromSeconds(GlobalConstant.CacheSecond),
            }).Wait();

            var model = new LoginCaptcha()
            {
                img=base64Str,
                uuid=uuid
            };

            return HandleData(model);
        }


        private SysUser GetUser(SysLoginRequest request)
        {
            var user = GCCEntrance.DBManager!.LocalDB!.Queryable<SysUser>().Where(x => x.user_name==request.user_name).First();

            return user;
        }

        private void UpdateUser(SysUser user, string login_IP)
        {
            var saveRes = GCCEntrance.DBManager!.LocalDB!.Update<SysUser>(user.id)
               .Set(item => item.login_ip, login_IP)
               .Set(item => item.login_date, DateTime.Now)
               .Set(item => item.token, user.token)

               .ExecuteAffrows()==1;
        }


        /// <summary>
        /// 查询角色
        /// </summary>
        /// <param name="user_id"></param>
        /// <returns></returns>
        private List<SysRole> GetRoles(long user_id)
        {
            var roles = GCCEntrance.DBManager!.LocalDB!.Select<SysRole, SysUserRole>().Where((r, ur) => ur.role_id==r.id&&ur.user_id==user_id).ToList();

            return roles;
        }

        /// <summary>
        /// 查询精确到按钮的操作权限
        /// </summary>
        /// <param name="role_ids"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        private List<string> GetPermission(List<long> role_ids, SysUser sysUser)
        {
            List<string> perms = new();
            if (sysUser.IsAdmin())
                perms.Add(GlobalConstant.AdminPerm);
            else
            {
                var menus = GCCEntrance.DBManager!.LocalDB!.Select<SysMenu, SysRole, SysRoleMenu>().Where((m, r, mr) => m.id==mr.menu_id&&r.id==mr.role_id&&role_ids.Contains(mr.role_id)&&m.menu_status==1&&r.status==1).ToList();
                perms.AddRange(menus.Where(x => !string.IsNullOrWhiteSpace(x.authorize)).Select(x => x.authorize).Distinct().ToList());
            }

            return perms;
        }
    }
}
